/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controller.Pronosticos;

import Entity.Periodo;
import java.util.ArrayList;

/**
 *
 * @author camilourd
 */
public class WinterCompleto extends MetodosPronosticos {

    public WinterCompleto() {
        super();
    }
    
    public void addPeriodo(String name, double demand, double previousDemand) {
        dmp.getPers().add(new Periodo(name, demand, previousDemand, 0));
    }
    
    public void addUt(double data) {
        dmp.setUt(data);
    }
    
    public void calcular(int numPers) {
        ArrayList<Periodo> pers = dmp.getPers();
        double sumDt = 0, sumDta = 0, sumI = 0, data;
        int n = pers.size();
        
        if(n > 0) {
            for(Periodo p: pers) {
                sumDt += p.getDemanda();
                sumDta += p.getDemandaAnterior();
            }
            
            // Obtener datos
            double alpha = dmp.getAlpha();
            double beta = dmp.getBeta();
            double gamma = dmp.getGamma();
            double m = dmp.getUt();
            double invalpha = 1.0 - alpha;
            double invbeta = 1.0 - beta;
            double invgamma = 1.0 - gamma;
            // promedios
            double pDt = sumDt / (1.0 * n);
            double pDta = sumDta / (1.0 * n);
            double T0 = (pDt - pDta) / m;
            double Xa = (m / 2.0) + 0.5;
            double F0 = pDt - (T0 * Xa);
            double F0a = pDta - (T0 * Xa);
            
            // Calcular Td y Tda
            for(int i = 1; i <= n; ++i) {
                pers.get(i - 1).setTd(F0 + (T0 * i));
                pers.get(i - 1).setTda(F0a + (T0 * i));
            }
            
            // Calcular I Ia Ip
            for(Periodo p: pers) {
                p.setI(p.getDemanda() / p.getTd());
                p.setIa(p.getDemandaAnterior() / p.getTda());
                p.setIp((p.getI() + p.getIa()) / 2.0);
                sumI += p.getIp();
            }
            
            // ajuste
            double ca;
            while(Math.abs(sumI - (1.0 * n)) > 0.005) {
                ca = (1.0 * n) / sumI;
                sumI = 0;
                
                for(Periodo p: pers) {
                    p.setIp(p.getIp() * ca);
                    sumI += p.getIp();
                }
            }
            
            // cálculos
            for(int i = 0;i < n; ++i) {
                if(i > 0) {
                    // calcular Ft
                    data = ((alpha * pers.get(i).getDemanda()) / pers.get(i).getIp())
                            + (invalpha * (pers.get(i - 1).getFt() + pers.get(i - 1).getTt()));
                    pers.get(i).setFt(data);
                    // Calcular Tt
                    data = ((beta * (pers.get(i).getFt() - pers.get(i - 1).getFt())))
                            + (invbeta * pers.get(i - 1).getTt());
                    pers.get(i).setTt(data);
                } else {
                    // calcular Ft
                    data = ((alpha * pers.get(i).getDemanda()) / pers.get(i).getIp()) + (invalpha * (F0 + T0));
                    pers.get(i).setFt(data);
                    // Calcular Tt
                    data = ((beta * (pers.get(i).getFt() - F0))) + (invbeta * T0);
                    pers.get(i).setTt(data);
                }
                // Calcular It
                data = (gamma * (pers.get(i).getDemanda() / pers.get(i).getFt())) + (invgamma * pers.get(i).getIp());
                pers.get(i).setIt(data);
            }
            
            // Pronósticos
            double ftn = pers.get(n - 1).getFt();
            double ttn = pers.get(n - 1).getTt();
            double itn = pers.get(n - 1).getIt();
            dmp.getYp().add(pers.get(n - 1).getDemanda());
            
            for(int i = 1;i <= numPers; ++i) {
                data = (ftn + (ttn * i)) * itn;
                if(data < 0.0) data = 0.0;
                dmp.getYp().add(data);
            }
            
            double ypn = dmp.getYp().get(1);
            double ytn = pers.get(n - 1).getDemanda();
            // calcular errores
            calcularErrores(ytn, ypn, n * 1.0);
        }
    }
}
